package cn.spiral.core.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import cn.spiral.core.dao.BaseDao;
import cn.spiral.core.utils.PageResult;
import cn.spiral.core.utils.QueryHelper;

//这里不能加@repository，否则会自动建筑初始化方法，而这个的父类是HibernateDaoSupport，反射方法会报错的
public class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	@Autowired
	public void setMySessionFactory(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}
	Class<T> clazz;
	//初始化时根据传入的泛型类加载该实体类到clazz
	public BaseDaoImpl(){
		
		//1.获取T代表的具体对象，即传入的泛型对象
		//获得表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类(父类，即BaseDao)的 Type，然后将其转换ParameterizedType
		ParameterizedType type=(ParameterizedType) getClass().getGenericSuperclass();
		//通过该超类type获得传入的泛型对象集，[0]即表示第一个泛型对象
		clazz=(Class) type.getActualTypeArguments()[0];
	}
	@Override
	public void save(T entity) {
		this.getHibernateTemplate().save(entity);
		
	}
	@Override
	public void update(T entity) {
		this.getHibernateTemplate().update(entity);
		
	}
	@Override
	public void delete(Serializable id) {
		this.getHibernateTemplate().delete(this.findObjectById(id));
		
	}
	@Override
	public T findObjectById(Serializable id) {
		return getHibernateTemplate().get(clazz, id);
	}
	@Override
	public List<T> findObjects() {
		Query query=this.getSession().createQuery("FROM "+clazz.getSimpleName());
		return query.list();
	}
	
	@Override
	public List<T> findObjects(QueryHelper queryHelper) {
		Query query=this.getSession().createQuery(queryHelper.getListQueryHql());
		List<Object> parameters=queryHelper.getParameters();
		if(parameters!=null){
			for(int i=0;i<parameters.size();i++){
				query.setParameter(i, parameters.get(i));
			}
		}
		return query.list();
	}
	@Override
	public PageResult getPageResult(QueryHelper queryHelper, int pageNo, int pageSize) {

		Query query=this.getSession().createQuery(queryHelper.getListQueryHql());
		List<Object> parameters=queryHelper.getParameters();
		if(parameters!=null){
			for(int i=0;i<parameters.size();i++){
				query.setParameter(i, parameters.get(i));
			}
		}
		//如果查询没有结果，或没有设置传入的值，默认从第一页查找
		pageNo=pageNo==0?1:pageNo;
		query.setFirstResult((pageNo-1)*pageSize);
		query.setMaxResults(pageSize);
		List items =query.list();
		Query countQuery=this.getSession().createQuery(queryHelper.getCountHql());
		if(parameters!=null){
			for(int i=0;i<parameters.size();i++){
				countQuery.setParameter(i, parameters.get(i));
			}
		}
		//数据库中根据你的查询条件只会返回唯一结果，就可以用uniqueResult这个方法！否则就用list（）；其返回类型为Object 
		long count=(long) countQuery.uniqueResult();
		
		return new PageResult(count, pageNo, pageSize, items);
	}
}
